package com.vast.common.utils;

import cn.hutool.core.io.FileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class FileUtils {

    private static Logger logger = LoggerFactory.getLogger(FileUtils.class);

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");

	public static String location;

    @Value("${file.uploadFolder}")
    public void setLocation(String location) {
        if (!location.endsWith("/")) {
            location += "/";
        }
        FileUtils.location = location;
    }

    /**
     * 文件保存（app内图片与其他图片分开保存）
     * @param file
     * @param type TEMPLETE 模板文件 TMP 其他文件
     * @return
     */
    public static String uploadFile(MultipartFile file, FileType type) {
        String filePath = type.getValue() + "/";
        File root = new File(location + filePath);
        if (!root.exists()) {
            root.mkdirs();
        }
        String fileName = System.currentTimeMillis() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        File tmpFile = new File(location + filePath + fileName);
        if (!tmpFile.exists()) {
            try {
                file.transferTo(tmpFile);
                return filePath + fileName;
            } catch (IOException e) {
                logger.error("文件保存失败", e);
                return null;
            }
        } else {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return uploadFile(file, type);
        }
    }

    /**
     * 获取合同文件夹
     * @return
     */
    public static String getContractPath() {
        String filePath = FileType.CONTRACT.getValue() + "/" + simpleDateFormat.format(new Date()) + "/";
        File root = new File(location + filePath);
        if (!root.exists()) {
            root.mkdirs();
        }
        return filePath;
    }

    /**
     * 保存文件
     * @param bytes
     * @param type
     * @return
     */
    public static String saveFile(byte[] bytes, String fileName, FileType type) {
        String filePath = type.getValue() + "/";
        File root = new File(location + filePath);
        if (!root.exists()) {
            root.mkdirs();
        }
        File tmpFile = new File(location + filePath + fileName);
        try {
            org.apache.commons.io.FileUtils.writeByteArrayToFile(tmpFile, bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return filePath + fileName;
    }

    /**
     * 文件相对路径
     * @return 文件绝对路径
     */
    public static String getLocation() {
        return location;
    }

    /**
     * 文件相对路径
     * @return 文件绝对路径
     */
    public static String getLocation(FileType fileType) {
        return location + fileType.getValue() + "/";
    }

    /**
     * 移动文件至目标类型文件夹
     * @param source 源文件相对路径
     * @param targetFileType 目标文件类型
     * @return
     */
    public static String moveFile(String source, FileType targetFileType) throws IOException {
        String fileName = System.currentTimeMillis() + source.substring(source.lastIndexOf("."));
        String targetPath = targetFileType.getValue() + "/" + fileName;
        FileUtil.move(new File(location + source), new File(location + targetPath),true);
        return targetPath;
    }

	public static HttpServletResponse download(String path,String fileName, HttpServletResponse response) {
		try {
			// path是指欲下载的文件的路径。
			File file = new File(location+path);
			// 取得文件名。
			String filename = file.getName();
			// 取得文件的后缀名。
			String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
			// 以流的形式下载文件。
			InputStream fis = new BufferedInputStream(new FileInputStream(location+path));
			byte[] buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();
			// 清空response
			response.reset();
			// 设置response的Header
			response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("UTF-8"),"iso-8859-1"));
			response.addHeader("Content-Length", "" + file.length());
			OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
			response.setContentType("application/octet-stream");
			toClient.write(buffer);
			toClient.flush();
			toClient.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		return response;
	}


    public enum FileType {
        TEMPLETE("templete"), TMP("tmp"), SIGNATURE("signature"), CONTRACT("contract"), IMG("image");

        private String value;

        public String getValue() {
            return value;
        }

        FileType(String value) {
            this.value = value;
        }
    }

    /**
     * 判断文件是否是图片
     * @param file
     * @return
     */
    public static boolean isImage(File file) {
        if (!file.exists()) {
            return false;
        }
        BufferedImage image = null;
        try {
            image = ImageIO.read(file);
            if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) {
                return false;
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 判断文件是否是图片
     * @return
     */
    public static boolean isImage(String fileUrl) {
        if (StringUtils.isEmpty(fileUrl)) {
            return false;
        }
        BufferedImage image = null;
        try {
            image = ImageIO.read(new URL(fileUrl));
            if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) {
                return false;
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

}
